/**
 * 收藏夹数据模型
 * @author HalRui
 * @version 1.0.0
 * @description 基于Mongoose的收藏夹数据模型，定义用户自定义收藏夹的数据结构、验证规则和操作方法，支持公开/私密设置
 * @date 2025年9月27日
 */

const mongoose = require('mongoose');
const { connectDB } = require('../utils/db');

// 收藏夹模式定义
const collectionSchema = new mongoose.Schema({
    collectionId: {
        type: Number,
        required: true,
        description: "收藏夹唯一标识ID，自动递增生成"
    },
    userId: {
        type: Number,
        required: true,
        ref: 'UserInfos',
        description: "收藏夹所属用户ID，关联到UserInfos模型"
    },
    name: {
        type: String,
        required: true,
        maxlength: 50,
        description: "收藏夹名称，用于标识和区分不同收藏夹"
    },
    description: {
        type: String,
        maxlength: 200,
        default: '',
        description: "收藏夹详细描述信息，用于说明收藏夹的用途或内容"
    },
    coverImage: {
        type: String,
        default: '',
        description: "收藏夹封面图片URL或路径"
    },
    privacy: {
        type: String,
        enum: ['public', 'private'],
        default: 'private',
        description: "收藏夹隐私设置：public-公开，private-私密"
    },
    videoCount: {
        type: Number,
        default: 0,
        description: "收藏夹内视频数量统计"
    },
    isDeleted: {
        type: Boolean,
        default: false,
        description: "软删除标记，true表示已删除但保留数据"
    },
    createAt: {
        type: Date,
        default: Date.now,
        description: "收藏夹创建时间"
    },
    updateAt: {
        type: Date,
        default: Date.now,
        description: "收藏夹最后更新时间"
    }
});

// 创建索引
collectionSchema.index({ userId: 1, createAt: -1 });
collectionSchema.index({ collectionId: 1 }, { unique: true });
collectionSchema.index({ privacy: 1, createAt: -1 });

// 自动递增collectionId的中间件
collectionSchema.pre('save', async function(next) {
    if (this.isNew) {
        try {
            const lastCollection = await this.constructor.findOne({}, {}, { sort: { collectionId: -1 } });
            this.collectionId = lastCollection ? lastCollection.collectionId + 1 : 1;
        } catch (error) {
            return next(error);
        }
    }
    this.updateAt = new Date();
    next();
});

// 静态方法：创建收藏夹
collectionSchema.statics.createCollection = async function(collectionData) {
    await connectDB();
    
    const { userId, name, description, privacy } = collectionData;
    
    // 验证必要字段
    if (!userId || !name) {
        throw new Error('用户ID和收藏夹名称不能为空');
    }
    
    // 检查用户收藏夹数量限制（最多20个）
    const userCollectionCount = await this.countDocuments({ 
        userId, 
        isDeleted: false 
    });
    
    if (userCollectionCount >= 20) {
        throw new Error('收藏夹数量已达上限（20个）');
    }
    
    // 检查同名收藏夹
    const existingCollection = await this.findOne({ 
        userId, 
        name: name.trim(), 
        isDeleted: false 
    });
    
    if (existingCollection) {
        throw new Error('收藏夹名称已存在');
    }
    
    const collection = new this({
        userId,
        name: name.trim(),
        description: description ? description.trim() : '',
        privacy: privacy || 'private'
    });
    
    const savedCollection = await collection.save();
    return savedCollection;
};

// 静态方法：获取用户收藏夹列表
collectionSchema.statics.getUserCollections = async function(options) {
    await connectDB();
    
    const { 
        userId, 
        viewerId, 
        page = 1, 
        limit = 20, 
        sortBy = 'createAt', 
        sortOrder = 'desc' 
    } = options;
    
    const query = { 
        userId, 
        isDeleted: false 
    };
    
    // 如果不是本人查看，只显示公开的收藏夹
    if (viewerId !== userId) {
        query.privacy = 'public';
    }
    
    const sortOptions = {};
    sortOptions[sortBy] = sortOrder === 'desc' ? -1 : 1;
    
    const skip = (page - 1) * limit;
    
    const [collections, total] = await Promise.all([
        this.find(query)
            .sort(sortOptions)
            .skip(skip)
            .limit(limit)
            .lean(),
        this.countDocuments(query)
    ]);
    
    return {
        collections,
        pagination: {
            page,
            limit,
            total,
            pages: Math.ceil(total / limit)
        }
    };
};

// 静态方法：获取收藏夹详情
collectionSchema.statics.getCollectionDetail = async function(collectionId, viewerId) {
    await connectDB();
    
    const collection = await this.findOne({ 
        collectionId, 
        isDeleted: false 
    }).lean();
    
    if (!collection) {
        return null;
    }
    
    // 检查访问权限
    if (collection.privacy === 'private' && collection.userId !== viewerId) {
        throw new Error('无权限访问此收藏夹');
    }
    
    return collection;
};

// 静态方法：更新收藏夹
collectionSchema.statics.updateCollection = async function(collectionId, userId, updateData) {
    await connectDB();
    
    const collection = await this.findOne({ 
        collectionId, 
        userId, 
        isDeleted: false 
    });
    
    if (!collection) {
        throw new Error('收藏夹不存在');
    }
    
    // 如果更新名称，检查是否重名
    if (updateData.name && updateData.name.trim() !== collection.name) {
        const existingCollection = await this.findOne({ 
            userId, 
            name: updateData.name.trim(), 
            isDeleted: false,
            collectionId: { $ne: collectionId }
        });
        
        if (existingCollection) {
            throw new Error('收藏夹名称已存在');
        }
        
        collection.name = updateData.name.trim();
    }
    
    if (updateData.description !== undefined) {
        collection.description = updateData.description.trim();
    }
    
    if (updateData.privacy) {
        collection.privacy = updateData.privacy;
    }
    
    if (updateData.coverImage !== undefined) {
        collection.coverImage = updateData.coverImage;
    }
    
    collection.updateAt = new Date();
    await collection.save();
    
    return collection;
};

// 静态方法：删除收藏夹
collectionSchema.statics.deleteCollection = async function(collectionId, userId) {
    await connectDB();
    
    const collection = await this.findOne({ 
        collectionId, 
        userId, 
        isDeleted: false 
    });
    
    if (!collection) {
        throw new Error('收藏夹不存在');
    }
    
    // 软删除收藏夹
    collection.isDeleted = true;
    collection.updateAt = new Date();
    await collection.save();
    
    // 将该收藏夹中的收藏移动到默认收藏夹
    const Favorites = mongoose.model('Favorites');
    await Favorites.updateMany(
        { collectionId, isDeleted: false },
        { collectionId: null, updateAt: new Date() }
    );
    
    return { success: true };
};

// 静态方法：更新收藏夹视频数量
collectionSchema.statics.updateVideoCount = async function(collectionId, increment) {
    await connectDB();
    
    if (collectionId === null) {
        return; // 默认收藏夹不需要更新计数
    }
    
    const result = await this.updateOne(
        { collectionId, isDeleted: false },
        { 
            $inc: { videoCount: increment },
            updateAt: new Date()
        }
    );
    
    return result.modifiedCount > 0;
};

// 静态方法：获取热门公开收藏夹
collectionSchema.statics.getPopularCollections = async function(options) {
    await connectDB();
    
    const { limit = 20, timeRange = '7d' } = options;
    
    // 计算时间范围
    const now = new Date();
    let startDate;
    switch (timeRange) {
        case '1d':
            startDate = new Date(now.getTime() - 24 * 60 * 60 * 1000);
            break;
        case '7d':
            startDate = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
            break;
        case '30d':
            startDate = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
            break;
        default:
            startDate = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
    }
    
    const collections = await this.find({
        privacy: 'public',
        isDeleted: false,
        createAt: { $gte: startDate },
        videoCount: { $gt: 0 }
    })
    .sort({ videoCount: -1, createAt: -1 })
    .limit(limit)
    .lean();
    
    return collections;
};

// 实例方法：获取安全的JSON数据
collectionSchema.methods.getSafeJSON = function() {
    const collection = this.toObject();
    delete collection._id;
    delete collection.__v;
    return collection;
};

const Collections = mongoose.model('Collections', collectionSchema);

module.exports = Collections;